// 蜂窝蜜造平台生成代码，如手工更改，请添加到 .beeignore 忽略生成

package com.fowo.api.portal.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.fowo.api.common.model.PageSearch;
import com.fowo.api.common.query.QueryGenerator;
import com.fowo.api.portal.entity.Desktop;
import com.fowo.api.portal.entity.DesktopScheme;
import com.fowo.api.portal.mapper.DesktopMapper;
import com.fowo.api.portal.model.DesktopAddUpdateVo;
import com.fowo.api.portal.model.DesktopSearchParamPo;
import com.fowo.api.portal.model.DesktopVo;
import com.fowo.api.portal.service.DesktopSchemeService;
import com.fowo.api.portal.service.DesktopService;
import com.fowo.api.sys.entity.SysUser;
import com.fowo.api.sys.model.NewSerialRequest;
import com.fowo.api.sys.service.FileService;
import com.fowo.api.sys.service.SysImportTemplateService;
import com.fowo.api.sys.service.SysSerialService;
import com.fowo.api.sys.service.SysUserService;
import com.fowo.api.user.model.JwtUserInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.ArrayStack;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.validation.Validator;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 门户表 服务实现类
 *
 * @author 蜂窝蜜造平台 配置人：孙智远
 */
@Service
@Slf4j
@DS("ds21")
public class DesktopServiceImpl
        extends ServiceImpl<DesktopMapper, Desktop>
        implements DesktopService {

    public static final Map<String, String> SORT_FIELD_MAP = new HashMap<>();
    // 导出时单次查询最大记录数
    protected static final int EXPORT_QUERY_MAX_SIZE = 1000;
    // 支持导出的最大记录数(1048576 为 Excel 支持的最大行数)
    protected static final long EXPORT_MAX_SIZE = 1048575;

    @Resource
    private SysSerialService sysSerialService;

    @Resource
    protected FileService fileService;

    @Resource
    protected SysImportTemplateService importTemplateService;

    @Resource
    protected Validator validator;

    @Resource
    private DesktopSchemeService desktopSchemeService;


    @Resource
    private SysUserService sysUserService;

    @Override
    public Page<Desktop> pageSearch(DesktopSearchParamPo search) {
        Desktop desktop = BeanUtil.copyProperties(search, Desktop.class);
        QueryWrapper<Desktop> desktopQueryWrapper = QueryGenerator.initQueryWrapper(desktop, search);
        desktopQueryWrapper.eq("del_flag", 0);
        Page<Desktop> pageList = this.page(search.toPage(), desktopQueryWrapper);
        return pageList;
    }

    @Override
    public DesktopVo getVoById(Long id) {
        DesktopVo desktopVo = new DesktopVo();
        Desktop vo = this.getById(id);
        if (vo == null) {
            return null;
        }

        BeanUtil.copyProperties(vo, desktopVo);
        desktopVo.setDesktopScheme(desktopSchemeService.getById(vo.getCurrentSchemeId()));
        return desktopVo;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long create(DesktopAddUpdateVo vo) throws Exception {
        JwtUserInfo currentUser = JwtUserInfo.fromHeader();
        Desktop desktop = new Desktop();
        DesktopScheme desktopScheme = new DesktopScheme();
        BeanUtils.copyProperties(vo, desktop);
        desktop.setId(IdUtil.getSnowflakeNextId());
        String number = sysSerialService.getNewSerial(new NewSerialRequest(null, "Desktop.encode"));
        desktop.setEnEode(number);
        desktop.setCreateTime(new Date());
        desktop.setLastUpdateTime(new Date());
        if (currentUser != null) {
            desktop.setCreateUser(currentUser.getUserId());
            desktop.setLastUpdateUser(currentUser.getUserId());
        }

        if (vo.getJson() != null) {
            desktopScheme.setId(IdUtil.getSnowflakeNextId());
            desktopScheme.setDesktopId(desktop.getId().toString());
            desktopScheme.setFormData(vo.getJson());
            desktopScheme.setCreateTime(new Date());
            desktopScheme.setLastUpdateTime(new Date());
            desktopScheme.setCreateUser(currentUser.getUserId());
            desktopScheme.setLastUpdateUser(currentUser.getUserId());
            desktop.setCurrentSchemeId(desktopScheme.getId().toString());
        }
        if (this.save(desktop) && desktopSchemeService.save(desktopScheme)) {
            return desktop.getId();
        }
        throw new Exception("接口认证保存失败");
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean updateEdit(DesktopAddUpdateVo vo) throws Exception {
        JwtUserInfo currentUser = JwtUserInfo.fromHeader();
        Desktop desktopById = new Desktop();
        DesktopScheme desktopScheme = new DesktopScheme();
        BeanUtils.copyProperties(
                vo,
                desktopById
        );
        Desktop byId = this.getById(desktopById.getId());
        if (byId == null) {
            throw new Exception("接口认证不存在！");
        }
        desktopById.setLastUpdateTime(new Date());
        if (currentUser != null) {
            desktopById.setLastUpdateUser(currentUser.getUserId());
        }
        if (vo.getJson() != null) {
            desktopScheme = desktopSchemeService.getOne(Wrappers.<DesktopScheme>lambdaQuery().eq(DesktopScheme::getDesktopId, desktopById.getId()).eq(StrUtil.isNotBlank(desktopById.getCurrentSchemeId()), DesktopScheme::getId, desktopById.getCurrentSchemeId()), false);
            if (ObjectUtil.isNotNull(desktopScheme)) {
                desktopScheme.setFormData(vo.getJson());
                desktopScheme.setLastUpdateTime(new Date());
                desktopScheme.setLastUpdateUser(currentUser.getUserId());
                desktopById.setCurrentSchemeId(desktopScheme.getId().toString());
                desktopSchemeService.updateById(desktopScheme);
            }
        }
        if (this.updateById(desktopById)) {
            return true;
        }
        return false;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean publishScheme(DesktopAddUpdateVo vo) throws Exception {
        JwtUserInfo currentUser = JwtUserInfo.fromHeader();
        Desktop desktopById = new Desktop();
        DesktopScheme desktopScheme = new DesktopScheme();
        BeanUtils.copyProperties(
                vo,
                desktopById
        );
        Desktop byId = this.getById(desktopById.getId());
        if (byId == null) {
            throw new Exception("接口认证不存在！");
        }
        desktopById.setLastUpdateTime(new Date());
        if (currentUser != null) {
            desktopById.setLastUpdateUser(currentUser.getUserId());
        }
        if (vo.getJson() != null) {
            desktopScheme.setId(IdUtil.getSnowflakeNextId());
            desktopScheme.setDesktopId(desktopById.getId().toString());
            desktopScheme.setFormData(vo.getJson());
            desktopScheme.setCreateTime(new Date());
            desktopScheme.setLastUpdateTime(new Date());
            desktopScheme.setCreateUser(currentUser.getUserId());
            desktopScheme.setLastUpdateUser(currentUser.getUserId());
            desktopById.setCurrentSchemeId(desktopScheme.getId().toString());
            desktopSchemeService.save(desktopScheme);
        }
        if (this.updateById(desktopById)) {
            return true;
        }
        return false;
    }

    @Override
    public Boolean delete(Long id) throws Exception {
        if (id != null && id != 0) {
            UpdateWrapper<Desktop> updateWrapper = new UpdateWrapper<>();
            updateWrapper.set("del_flag", 1);
            updateWrapper.eq("id", id);
            if (this.update(updateWrapper)) {
                return true;
            }
        } else {
            throw new Exception("请检查参数");
        }
        return false;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean CopyDeskTop(Long id) throws Exception {
        try {
            JwtUserInfo currentUser = JwtUserInfo.fromHeader();
            if (Objects.isNull(currentUser)) {
                throw new Exception("请先登录！");
            }
            /**
             * 主表复制
             */
            Desktop desktop = this.lambdaQuery().eq(Desktop::getId, id).eq(Desktop::getDelFlag, "false").one();
            Desktop desktopNew = new Desktop();
            BeanUtil.copyProperties(desktop, desktopNew);
            desktopNew.setId(IdUtil.getSnowflakeNextId());
            desktopNew.setFullName(StrUtil.concat(true, desktop.getFullName(), "-副本"));
            desktopNew.setCreateTime(new Date());
            desktopNew.setType(0L);
            String number = sysSerialService.getNewSerial(new NewSerialRequest(null, "Desktop.encode"));
            desktopNew.setEnEode(number);
            desktopNew.setLastUpdateTime(new Date());
            desktopNew.setCreateUser(currentUser.getUserId());
            desktopNew.setLastUpdateUser(currentUser.getUserId());
            DesktopScheme desktopScheme = desktopSchemeService.lambdaQuery().eq(DesktopScheme::getId, desktop.getCurrentSchemeId()).one();
            /**
             * 子表部分
             */
            List<DesktopScheme> desktopSchemeList = desktopSchemeService.lambdaQuery().eq(DesktopScheme::getDesktopId, id).eq(DesktopScheme::getDelFlag, "false").list();
            if (!CollectionUtils.isEmpty(desktopSchemeList)) {
                desktopSchemeList.forEach(e -> {
                    e.setId(IdUtil.getSnowflakeNextId());
                    e.setDesktopId(desktopNew.getId().toString());
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                });
            }
            DesktopScheme scheme = desktopSchemeList.stream().filter(item -> item.getFormData().equals(desktopScheme.getFormData())).collect(Collectors.toList()).get(0);
            desktopNew.setCurrentSchemeId(scheme.getId().toString());

            if (this.save(desktopNew) && desktopSchemeService.saveBatch(desktopSchemeList)) {
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public Boolean switchVersion(Long id) throws Exception {
        try {
            JwtUserInfo currentUser = JwtUserInfo.fromHeader();
            if (Objects.isNull(currentUser)) {
                throw new Exception("请先登录！");
            }
            DesktopScheme desktopScheme = desktopSchemeService.lambdaQuery().eq(DesktopScheme::getId, id).eq(DesktopScheme::getDelFlag, "false").one();
            Desktop desktop = this.lambdaQuery().eq(Desktop::getId, desktopScheme.getDesktopId()).eq(Desktop::getDelFlag, "false").one();
            if (Objects.nonNull(desktopScheme) && Objects.nonNull(desktop)) {
                desktop.setCurrentSchemeId(desktopScheme.getId().toString());
                desktop.setLastUpdateTime(new Date());
                desktop.setLastUpdateUser(currentUser.getUserId());
                this.updateById(desktop);
            } else {
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    @Override
    public Page<Desktop> getHistoryPage(Long id, PageSearch pageSearch) {
        Desktop desktop = this.getById(id);
        List<Desktop> res =new ArrayList<>();
        IPage<DesktopScheme> page = desktopSchemeService.page(pageSearch.toPage(), Wrappers.<DesktopScheme>lambdaQuery().eq(DesktopScheme::getDesktopId, id).eq(DesktopScheme::getDelFlag, false).orderByAsc(DesktopScheme::getId));
        for (DesktopScheme desktopScheme : page.getRecords()) {
            Desktop ds = BeanUtil.copyProperties(desktop, Desktop.class);
            SysUser user = sysUserService.getById(ds.getCreateUser());
            ds.setUsername(ObjectUtil.isNotNull(user) ? user.getName() : "管理员");
            ds.setRolenames("管理层");
            ds.setSchemeId(desktopScheme.getId().toString());
            ds.setLastUpdateTime(desktopScheme.getLastUpdateTime());
            ds.setLastUpdateUser(desktopScheme.getLastUpdateUser());
            res.add(ds);
        }
        return pageSearch.toPage().setRecords(res).setTotal(page.getTotal());
    }

    @Override
    public String previewDeskSchemeJson(Long id) {
        DesktopScheme desktopSchemeServiceById = desktopSchemeService.getById(id);
        return desktopSchemeServiceById.getFormData();
    }
}
